package algo3.algothief.controlador;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map.Entry;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import algo3.algothief.excepcion.CasoNoIniciadoException;
import algo3.algothief.excepcion.LugarInvalidoParaVisitarDesdeEPaislActualException;
import algo3.algothief.modelo.EsconditeDeLadron;
import algo3.algothief.modelo.Juego;
import algo3.algothief.modelo.LugarDePais;
import algo3.algothief.vista.VistaJuego;

public class ControladorVisita {

	private Juego juego;
	
	private VistaJuego vistaDelJuego;
	
	private HashMap<String, String> opcionesParaVisitar;
	
//---------------------------------------------------------------------------------------------------------
	
	public ControladorVisita(Juego juegoActual, VistaJuego vista) throws CasoNoIniciadoException {
		this.juego = juegoActual;
		
		this.vistaDelJuego = vista;
		
		this.opcionesParaVisitar = this.crearOpcionesParaVisitar();
	}

//---------------------------------------------------------------------------------------------------------

	private HashMap<String, String> crearOpcionesParaVisitar() throws CasoNoIniciadoException {
		HashMap<String, String> opciones = new HashMap<String, String>();
		
		HashMap<String, LugarDePais> lugares = juego.verQueLugaresSePuedenVisitar();
		
		Integer i = 1;
		for (Entry<String, LugarDePais> opcion : lugares.entrySet()) {
			String nombreDelLugar = opcion.getKey();
			opciones.put(i.toString(), nombreDelLugar);
			i++;
		}
		
		return opciones;
	}
	
	private LugarDePais procesarLugarParaVisitar(BufferedReader entradaDeTeclado) throws IOException, CasoNoIniciadoException {
		String entrada = entradaDeTeclado.readLine();
		
		String opcionParaVolverAlMenuPrincipal = Integer.toString(0);
				
		while ( (!opcionesParaVisitar.containsKey(entrada)) && (!opcionParaVolverAlMenuPrincipal.matches(entrada)) ) {
			VistaJuego.graficarMensajeDeOpcionElegidaIncorrecta(entradaDeTeclado);
			
			vistaDelJuego.graficarMenuDePosiblesLugaresParaVisitar(opcionesParaVisitar);
			entrada = entradaDeTeclado.readLine();
		}
		
		String nombreDelLugar = opcionesParaVisitar.get(entrada);
		HashMap<String, LugarDePais> lugares = juego.verQueLugaresSePuedenVisitar();
		
		return lugares.get(nombreDelLugar);
	}

	
	
	private void procesarUnPosibleEncuentroConElLadron(LugarDePais lugarElegido, String pistaParaElJugador, BufferedReader entradaDeTeclado) throws IOException, CasoNoIniciadoException {
		if (juego.seLlegoAlUltimoPaisDelCaso()) {
			EsconditeDeLadron esconditeDelLadron = (EsconditeDeLadron)lugarElegido;
			int tiempoQueSeTardoPorLaRecuperacionDeLaHerida = esconditeDelLadron.verElTiempoTranscurridoPorObtenerLaPista();
			
			if (tiempoQueSeTardoPorLaRecuperacionDeLaHerida == 4)
				vistaDelJuego.graficarMensajeDeHeridaDeBala(entradaDeTeclado);
			else if (tiempoQueSeTardoPorLaRecuperacionDeLaHerida == 2)
				vistaDelJuego.graficarMensajeDeHeridaDeCuchillo(entradaDeTeclado);
		}	
			
		vistaDelJuego.graficarMensajeConPistaParaElJugador(pistaParaElJugador, entradaDeTeclado);
	}
	
//---------------------------------------------------------------------------------------------------------
	
	public void procesarEntradasParaVisitar(BufferedReader entradaDeTeclado) throws ParserConfigurationException, SAXException, IOException, CasoNoIniciadoException {
		vistaDelJuego.graficarMenuDePosiblesLugaresParaVisitar(opcionesParaVisitar);
		LugarDePais lugarElegido = this.procesarLugarParaVisitar(entradaDeTeclado);
		
		if (lugarElegido != null) {
			try {
				String pistaParaElJugador = juego.visitar(lugarElegido);
			
				if (juego.sePuedeSeguirJugando())
					this.procesarUnPosibleEncuentroConElLadron(lugarElegido, pistaParaElJugador, entradaDeTeclado);
			} catch (LugarInvalidoParaVisitarDesdeEPaislActualException excepcion) {
				// Nunca se llega a la situacion en que se elija un 
				// LugarDePais que no este entre los propuestos.
				VistaJuego.graficarMensajeDeError(excepcion);
			}
		}
	}
}